package com.gemantic.glue.exec;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gemantic.glue.context.GlueExecContext;
import com.gemantic.glue.context.GlueExecHelper;

import com.gemantic.glue.handler.IGlueHandler;
import com.gemantic.glue.log.JobFileAppender;
import com.gemantic.glue.model.TriggerParam;


/**
 * handler thread
 *
 * @author xuxueli 2016-1-16 19:52:47
 */
public class ExecutorHandler {
    private static Logger logger = LoggerFactory.getLogger(ExecutorHandler.class);

    private long jobId;
    private IGlueHandler handler;
    private TriggerParam triggerParam;
    private String stopReason;


    public ExecutorHandler(long jobId, IGlueHandler handler) {
        this.jobId = jobId;
        this.handler = handler;
        this.triggerParam = null;
    }

    public IGlueHandler getHandler() {
        return handler;
    }


    public void toStop(String stopReason) {
        this.stopReason = stopReason;
    }

    public void run(TriggerParam triggerParam) {

        // init
        try {
            handler.init();
        } catch (Throwable e) {
            logger.error(e.getMessage(), e);
        }

        try {
            // log filename, like "logPath/yyyy-MM-dd/9999.log"
            String logFileName = JobFileAppender.makeLogFileName(new Date(triggerParam.getLogDateTime()), triggerParam.getLogId());
            GlueExecContext glueExecContext = new GlueExecContext(triggerParam.getJobId(), triggerParam.getExecutorParams(), logFileName, triggerParam.getBroadcastIndex(), triggerParam.getBroadcastTotal(), triggerParam.getPack());

            // init job context
            GlueExecContext.setXxlJobContext(glueExecContext);

            // execute
            GlueExecHelper.log("glue-handler execute start:" + glueExecContext.getJobParam());

            handler.execute();

            // valid execute handle data
            if (GlueExecContext.getXxlJobContext().getHandleCode() <= 0) {
                GlueExecHelper.handleFail("job handle result lost.");
            } else {
                String tempHandleMsg = GlueExecContext.getXxlJobContext().getHandleMsg();
                tempHandleMsg = (tempHandleMsg != null && tempHandleMsg.length() > 50000) ? tempHandleMsg.substring(0, 50000).concat("...") : tempHandleMsg;
                GlueExecContext.getXxlJobContext().setHandleMsg(tempHandleMsg);
            }
            GlueExecHelper.log("glue-handler execute endResult: " + ", handleMsg = " + GlueExecContext.getXxlJobContext().getHandleMsg());


        } catch (Throwable e) {

            // handle result
            StringWriter stringWriter = new StringWriter();
            e.printStackTrace(new PrintWriter(stringWriter));
            String errorMsg = stringWriter.toString();

            GlueExecHelper.handleFail(errorMsg);

            GlueExecHelper.log("glue-handler  Exception:" + errorMsg);
        }

        try {
            handler.destroy();
        } catch (Throwable e) {
            logger.error(e.getMessage(), e);
        }
    }
}
